Skip to content

feat(api): add a std::pmr::memory_resource adapter (PoolMemoryResource)#113

Merged
danielPoloWork merged 2 commits into
masterfrom
feat/pmr-memory-resource
Jul 7, 2026
Merged

feat(api): add a std::pmr::memory_resource adapter (PoolMemoryResource)#113
danielPoloWork merged 2 commits into
masterfrom
feat/pmr-memory-resource

Conversation

@danielPoloWork

Copy link
Copy Markdown
Owner

Summary

Adds it::d4np::memorypool::PoolMemoryResource, a std::pmr::memory_resource Adapter that
binds one Pool behind the runtime std::pmr interface — so a single resource can back
any std::pmr container (via std::pmr::polymorphic_allocator) without the per-type
PoolAllocator<T> rebind. This is the "door left open" in ADR-0018. Header-only and purely
additive
— the frozen C ABI and the existing C++ types are unchanged, so this is a SemVer
MINOR (v1.2.0 candidate). It opens roadmap Milestone 9.

Motivation

PoolAllocator<T> (ADR-0018) bakes the pool into a container's type; std::pmr chooses the
storage policy at run time by handing a container a memory_resource*. ADR-0018 recorded the
pmr resource as deferred, not rejected. Issue #107 / Milestone 9 opens it.

Changes

  • pool_memory_resource.hppPoolMemoryResource : public std::pmr::memory_resource. A
    non-owning back-reference to a Pool plus a configurable upstream resource. Deterministic
    (bytes, alignment) routing (mirroring ADR-0018 §2): fitting requests come from the pool
    (throwing std::bad_alloc on exhaustion — never falling back, so do_deallocate routes
    deterministically); over-sized / over-aligned requests go upstream
    (std::pmr::get_default_resource() by default). do_is_equal by (pool, upstream) identity.
    Gated behind PBR_MEMORY_POOL_HAS_PMR (a __cpp_lib_memory_resource feature-test) so the
    header is a no-op where <memory_resource> is unavailable.
  • ADR-0042 — records the decision (routing, non-owning shape, exhaustion-throws-not-falls-back,
    configurable upstream, availability gate) and the rejected alternatives; ADR index row added.
  • Dedicated doctest pool_memory_resource_test — gated like the header; proves pool routing +
    exhaustion + reissue, upstream routing (via null_memory_resource), is_equal, and an
    end-to-end std::pmr::list / std::pmr::vector / polymorphic_allocator round-trip.
  • Spec — §5.2 lists the type, §7 maps it to ADR-0042, §7.1 no longer defers it.
  • ROADMAP — Milestone 9 created (ADR-0037) with this as item 9.1; feat(cpp): opt-in debug hardening — freed-block poisoning, canaries, free-list safe-linking #109/test(ci): add a coverage-guided fuzzing harness for the pool surface #108/perf(bench): add jemalloc/tcmalloc baselines and p99 tail-latency reporting #111 listed as 9.2–9.4.
  • Doxyfile — predefines __cpp_lib_memory_resource so the gated class appears on the API site.
  • CHANGELOG[Unreleased] Added entry.

Design Patterns

  • Adapter — a second realisation of the already-catalogued Adapter (ADR-0018), bridging the
    pool to the runtime std::pmr::memory_resource interface. No new pattern is introduced.

Verification

  • MSVC build clean; pool_memory_resource doctest 5 cases / 33 assertions pass.
  • clang-format (22.x) clean; clang-tidy clean on the header + test (the (bytes, alignment)
    bugprone-easily-swappable-parameters findings are the fixed std::pmr override signature —
    suppressed with rationale).
  • python tools/consistency_lint.pyOK.
  • Full toolchain matrix / ASan / UBSan / TSan — via CI (the adapter runs under the existing
    test matrix; no threading added).

Documentation Impact

  • ADR added (ADR-0042) + index row.
  • Spec updated (§5.2, §7 map, §7.1).
  • ROADMAP Milestone 9 created (ADR-0037).
  • CHANGELOG [Unreleased] entry.
  • PR metadata — assignee, feat label, v1.2.0 milestone.
  • Deferred to the v1.2.0 release PR (to keep this feature PR off the translated docs
    surface — editing them trips the i18n-freshness gate): the README.md Milestone-9 table row
    (a release-time refresh per M8.8) and the docs/patterns/README.md Adapter-row refinement (the
    Adapter pattern is already catalogued; the pmr application is fully documented in ADR-0042 and
    the spec §7 map). The release PR refreshes both and re-syncs the zh-Hans / ja translations
    in one pass. The spec rows remain stale (already flagged since docs(spec): reconcile the memory-pool spec with the as-built system #110/docs(spec): add a C4 component diagram and record Mermaid as the diagram tooling #112).

Closes #107.

PoolMemoryResource binds one Pool behind the runtime
std::pmr::memory_resource interface, so a single resource can back any
std::pmr container via std::pmr::polymorphic_allocator without the
per-type PoolAllocator<T> rebind — the "door left open" in ADR-0018.

Deterministic (bytes, alignment) routing to the bound pool: fitting
requests come from the pool (throwing std::bad_alloc on exhaustion,
never falling back, so deallocate routing stays deterministic);
over-sized / over-aligned requests delegate to a configurable upstream
resource (get_default_resource() by default). is_equal compares
(pool, upstream) identity. The whole facility is gated behind
PBR_MEMORY_POOL_HAS_PMR (a __cpp_lib_memory_resource feature-test) so
the header is a harmless no-op where std::pmr is unavailable.

Header-only and purely additive: the frozen C ABI and the existing C++
types are unchanged, so this is a SemVer MINOR. It opens roadmap
Milestone 9 (post-1.0 ergonomics, hardening & tooling; ADR-0037).

- ADR-0042 records the decision (+ ADR index row).
- Dedicated doctest (pool_memory_resource), gated like the header.
- Spec §5.2 lists the type; §7 maps it to ADR-0042; §7.1 un-defers it.
- ROADMAP Milestone 9 created with this as item 9.1.
- Doxyfile predefines __cpp_lib_memory_resource so the gated class is
  documented on the API site.
- CHANGELOG [Unreleased] Added entry.

The README milestone-table row and the patterns-catalogue refinement
are deferred to the v1.2.0 release PR to keep this feature PR off the
translated docs surface (they would trip the i18n-freshness gate).

Validated locally: MSVC build + doctest (5 cases / 33 assertions),
clang-format and clang-tidy clean, consistency lint OK.

Closes #107

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@danielPoloWork danielPoloWork added this to the v1.2.0 milestone Jul 7, 2026
@danielPoloWork danielPoloWork added the feat New feature (Conventional Commit: feat) label Jul 7, 2026
@danielPoloWork danielPoloWork self-assigned this Jul 7, 2026
The link resolved to docs/adr/doxygen/Doxyfile (from the ADR directory)
and tripped the Lychee internal-link check; correct it to
../doxygen/Doxyfile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@danielPoloWork danielPoloWork marked this pull request as ready for review July 7, 2026 19:23
@danielPoloWork danielPoloWork merged commit d4afec5 into master Jul 7, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feat New feature (Conventional Commit: feat)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(cpp): add a std::pmr::memory_resource adapter (PoolMemoryResource)

1 participant